package com.je.meta.service.upgrade.impl;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.google.common.base.Strings;
import com.je.common.base.DynaBean;
import com.je.common.base.service.CommonService;
import com.je.common.base.service.MetaService;
import com.je.common.base.service.rpc.BeanService;
import com.je.common.base.upgrade.PackageFile;
import com.je.common.base.upgrade.PackageResult;
import com.je.common.base.upgrade.UpgradeResourcesEnum;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;
import com.je.meta.rpc.upgrade.UpgradelogRpcService;
import com.je.meta.service.upgrade.InstallResourceDTO;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.*;

public abstract class AbstractUpgradeMetaDate<T> {

    @Autowired
    protected MetaService metaService;
    @Autowired
    protected CommonService commonService;
    @Autowired
    protected UpgradelogRpcService upgradelogRpcService;

    public UpgradeResourcesEnum upgradeResourcesEnum;

    public AbstractUpgradeMetaDate(UpgradeResourcesEnum upgradeResourcesEnum) {
        this.upgradeResourcesEnum = upgradeResourcesEnum;
    }

    public abstract void packUpgradeMetaDate(T packageResult, DynaBean upgradeBean);

    /**
     * 安装资源
     *
     * @param upgradeInstallId  主键id
     * @param list              数据
     * @param productCode       产品code
     * @param customerParameter 自定义参数
     */
    public void installUpgradeMetaDate(String upgradeInstallId, List<DynaBean> list, String productCode, Map<String, Object> customerParameter) {
        installResources(new InstallResourceDTO.Builder()
                .upgradeInstallId(upgradeInstallId)
                .list(list)
                .productCode(productCode)
                .identifier(upgradeResourcesEnum.getContentBm())
                .tableCode(upgradeResourcesEnum.getTableCode())
                .logAdd(true)
                .logName(upgradeResourcesEnum.getName())
                .logType(upgradeResourcesEnum.getType())
                .logContentCode(upgradeResourcesEnum.getContentBm())
                .logContentName(upgradeResourcesEnum.getContentName())
                .build());
    }

    public List<String> getSourceIds(DynaBean upgradeBean) {
        return upgradeBean.get(upgradeResourcesEnum.getAddListName()) == null ? new ArrayList<>() : (List<String>) upgradeBean.get(upgradeResourcesEnum.getAddListName());
    }

    public List<DynaBean> getChildList(List<DynaBean> list, String childCode) {
        if (list == null || list.size() == 0) {
            return new ArrayList<>();
        }
        List<DynaBean> allChildList = new ArrayList<>();
        for (DynaBean dynaBean : list) {
            Object childObject = dynaBean.get(childCode);
            if (childObject == null) {
                continue;
            }
            // 检查 childObject 是否是 List 类型
            JSONArray jsonArray = (JSONArray) childObject;
            List<DynaBean> childList = new ArrayList<>();
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                DynaBean childDynaBean = JSONObject.parseObject(jsonObject.toString(), DynaBean.class);
                if (jsonObject.get("pkCode") != null) {
                    childDynaBean.pkCode(jsonObject.getString("pkCode"));
                }
                if (jsonObject.get("tableCode") != null) {
                    childDynaBean.set(BeanService.KEY_TABLE_CODE, jsonObject.getString("tableCode"));
                }
                childList.add(childDynaBean);
            }
            if (!childList.isEmpty()) {
                allChildList.addAll(childList);
            }
        }
        return allChildList;
    }

    /**
     * 打包资源
     *
     * @param packageResult
     * @param resourceIds
     * @return
     */
    public List<DynaBean> packageResources(PackageResult packageResult, List<String> resourceIds) {
        List<DynaBean> beanList = metaService.select(upgradeResourcesEnum.getTableCode(), ConditionsWrapper.builder()
                .in(upgradeResourcesEnum.getContentCode(), resourceIds));
        //设置附件信息
        List<PackageFile> packageFileList = getFiles(beanList);
        if (packageFileList.size() > 0) {
            packageResult.getFiles().addAll(packageFileList);
        }
        return beanList;
    }

    /**
     * 打包资源，按照树形排序字段 asc排序
     *
     * @param packageResult
     * @param resourceIds
     * @param orderField
     * @return
     */
    public List<DynaBean> packageResourcesOrderAsc(PackageResult packageResult, List<String> resourceIds, String orderField) {
        List<DynaBean> beanList = metaService.select(upgradeResourcesEnum.getTableCode(), ConditionsWrapper.builder()
                .in(upgradeResourcesEnum.getContentCode(), resourceIds).orderByAsc(orderField));
        //设置附件信息
        List<PackageFile> packageFileList = getFiles(beanList);
        if (packageFileList.size() > 0) {
            packageResult.getFiles().addAll(packageFileList);
        }
        return beanList;
    }

    public InstallResourceDTO buildAbstractDto(String upgradeInstallId, List<DynaBean> list, String productCode) {
        return new InstallResourceDTO.Builder()
                .upgradeInstallId(upgradeInstallId)
                .list(list)
                .productCode(productCode)
                .identifier(upgradeResourcesEnum.getContentBm())
                .tableCode(upgradeResourcesEnum.getTableCode())
                .logAdd(true)
                .logName(upgradeResourcesEnum.getName())
                .logType(upgradeResourcesEnum.getType())
                .logContentCode(upgradeResourcesEnum.getContentBm())
                .logContentName(upgradeResourcesEnum.getContentName())
                .build();
    }

    public void installResources(InstallResourceDTO installResourceDTO) {
        if (installResourceDTO.getList() == null || installResourceDTO.getList().size() == 0) {
            return;
        }
        for (DynaBean dynaBean : installResourceDTO.getList()) {
            if (Strings.isNullOrEmpty(installResourceDTO.getIdentifier())) {
                continue;
            }
            String[] identifierArray = installResourceDTO.getIdentifier().split(",");
            ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder();
            for (int i = 0; i < identifierArray.length; i++) {
                conditionsWrapper.eq(identifierArray[i], dynaBean.getStr(identifierArray[i]));
            }
            List<DynaBean> configList = metaService.select(installResourceDTO.getTableCode(),
                    conditionsWrapper);
            dynaBean.table(installResourceDTO.getTableCode());
            if (configList != null && configList.size() > 0) {
                commonService.buildModelModifyInfo(dynaBean);
                metaService.update(dynaBean, conditionsWrapper);
            } else {
                commonService.buildModelCreateInfo(dynaBean);
                commonService.buildModelModifyInfo(dynaBean);
                metaService.insert(dynaBean);
            }
            if (!installResourceDTO.isLogAdd()) {
                continue;
            }
            //记录升级日志
            upgradelogRpcService.saveUpgradelog(installResourceDTO.getUpgradeInstallId(),
                    installResourceDTO.getLogType(), installResourceDTO.getLogName(),
                    dynaBean.getStr(installResourceDTO.getLogContentName()), dynaBean.getStr(installResourceDTO.getLogContentCode()));
        }
    }

    public List<PackageFile> getFiles(List<DynaBean> beanList) {
        return getFiles(beanList, upgradeResourcesEnum.getTableCode());
    }

    public List<PackageFile> getFiles(List<DynaBean> beanList, String tableCode) {
        List<PackageFile> packageFileList = new ArrayList<>();
        Map<String, String> fileCodes = upgradeResourcesEnum.getFileCodes();
        if (fileCodes.size() == 0) {
            return packageFileList;
        }
        if (fileCodes.get(tableCode) == null) {
            return packageFileList;
        }
        //要打包的附件字段
        String fields = fileCodes.get(tableCode);
        String[] fieldArray = fields.split(",");

        for (DynaBean dynaBean : beanList) {
            for (String fieldKey : fieldArray) {
                String value = dynaBean.getStr(fieldKey);
                if (Strings.isNullOrEmpty(value)) {
                    continue;
                }
                packageFileList.add(new PackageFile.Builder()
                        .upgradeResourcesType(upgradeResourcesEnum.getType())
                        .fileCode(fieldKey)
                        .pkValue(dynaBean.getPkValue())
                        .tableCode(tableCode)
                        .value(value)
                        .build());
            }
        }
        return packageFileList;
    }


    /**
     * 按树形表的SY_PATH层级从小到大排序
     *
     * @param datalist
     * @return
     */
    protected List<DynaBean> sort(List<DynaBean> datalist) {
        if (datalist == null || datalist.size() == 0) {
            return datalist;
        }

        Map<String, Integer> map = new HashMap<>();
        for (DynaBean dynaBean : datalist) {
            String path = dynaBean.getStr("SY_PATH");
            String id = dynaBean.getPkValue();
            Integer level = StringUtil.isNotEmpty(path) ? path.split("/").length : 0;
            map.put(id, level);
        }

        List<Map.Entry<String, Integer>> list = new LinkedList<Map.Entry<String, Integer>>(map.entrySet());
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                return +((Comparable) ((Map.Entry) (o1)).getValue()).compareTo(((Map.Entry) (o2)).getValue());
            }
        });

        map.clear();
        List<DynaBean> newList = new ArrayList<>();
        for (Map.Entry<String, Integer> entry : list) {
            String key = entry.getKey();
            for (DynaBean dynaBean : datalist) {
                String id = dynaBean.getPkValue();
                if (key.equals(id)) {
                    newList.add(dynaBean);
                    break;
                }
            }
        }
        return newList;

    }

    public abstract List<DynaBean> extractNecessaryData(PackageResult packageResult);
}
